package prototipo.server.logic.util;

import prototipo.server.logic.exception.ExceptionLogic;

public class Cpf implements CpfIF {

	private String cpf;

	public Cpf(String newCpf) throws ExceptionLogic {
		this();
		this.setCpf(newCpf);
	}

	public Cpf() {
	}

	/**
	 * @return the cpf
	 */
	public String getCpf() {
		return cpf;
	}

	/**
	 * @param cpf
	 *            the cpf to set
	 * @throws ExceptionLogic
	 */
	public void setCpf(String cpf) throws ExceptionLogic {
		if (validateCpf(cpf))
			this.cpf = cpf;
		else
			throw new ExceptionLogic("Cpf invalido.", new Throwable(
					"Cpf failed."));

	}

	private boolean validateCpf(String cpf) throws ExceptionLogic {
		if (cpf == null)
			throw new ExceptionLogic("Cpf vazio.", new Throwable(
					"String is null."));
		if (cpf.length() != 11)
			throw new ExceptionLogic("Insira um cpf valido, 11 digitos.",
					new Throwable("Cpf String length is not 11."));
		boolean result = false;
		try {
			result = calcDigVerif(cpf.substring(0, 9)).equals(
					cpf.substring(9, 11));
		} catch (Exception e) {
			if (e.getMessage().equals("For input string: \"a\""))
				throw new ExceptionLogic("Cpf invalido.",
						new Throwable(e.getCause()));
		}
		return result;
	}

	private String calcDigVerif(String num) {
		Integer primDig, segDig;
		int soma = 0, peso = 10;
		for (int i = 0; i < num.length(); i++)
			soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
		if (soma % 11 == 0 | soma % 11 == 1)
			primDig = new Integer(0);
		else
			primDig = new Integer(11 - (soma % 11));
		soma = 0;
		peso = 11;
		for (int i = 0; i < num.length(); i++)
			soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
		soma += primDig.intValue() * 2;
		if (soma % 11 == 0 | soma % 11 == 1)
			segDig = new Integer(0);
		else
			segDig = new Integer(11 - (soma % 11));
		return primDig.toString() + segDig.toString();
	}

	public String toString() {
		return String.format("%s.%s.%s-%s", this.cpf.substring(0, 3), this.cpf
				.substring(3, 6), this.cpf.substring(6, 9), this.cpf.substring(
				9, 11));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cpf == null) ? 0 : cpf.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Cpf))
			return false;
		Cpf other = (Cpf) obj;
		if (cpf == null) {
			if (other.cpf != null)
				return false;
		} else if (!cpf.equals(other.cpf))
			return false;
		return true;
	}

}
